/**
 * Code examples taken from 
 *  http://blog.james-carr.org/2006/07/11/ssh-over-java/
 * 
 * using JSch library
 */


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.regex.Pattern;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UserInfo;





public class SshClient {
	
	BufferedReader fromServer;
	Pattern language = Pattern.compile("([^a-zA-Z0-9])");
	OutputStream toServer;
	
	String lastCommand = "";
	
	Channel channel;
	
	Session session;
	
	private static final String terminator = "###";
	
	/**
	 * Connects to remote computer by SSH
	 * @param username
	 * @param password
	 * @param host
	 * @param port
	 * @throws JSchException
	 * @throws IOException
	 */
	public void connect(String username, String password, String host, int port) throws JSchException, IOException {
		JSch shell = new JSch();
		session = shell.getSession(username, host, port);
		//shell.
		
		//create the class to hold all of the user information during connect
		MyUserInfo userInfo = new MyUserInfo();
		userInfo.setPassword(password);
		
		//set the current user and initiate connection
		session.setUserInfo(userInfo);
		session.setConfig("StrictHostKeyChecking", "no");
		//session.trust = true;
		session.connect();
		
		//more stuff
		channel = session.openChannel("shell");
		//set up stream to read incoming info from server
		fromServer = new BufferedReader(new InputStreamReader(channel.getInputStream()));
		toServer = channel.getOutputStream();
		channel.connect();
		if(channel != null && channel.isConnected()){
				execute("echo \"\"");
				System.out.println("SUCCESS!");

		}
		
	}
	
	
	public String execute(String command) throws IOException, JSchException {
		ChannelExec channel = (ChannelExec) session.openChannel("exec");
		channel.setCommand(command);
		channel.connect();
		BufferedReader reader = new BufferedReader(new InputStreamReader(channel.getInputStream()));
		StringBuilder responseBuilder = new StringBuilder();
		while (!channel.isClosed() && !channel.isEOF()) {
			String line = reader.readLine();
			if (line != null) {
				responseBuilder.append(line).append("\n");
			}
		}
		toServer.flush();
		return responseBuilder.toString();
	}
	
	public void sendPass(String command) throws IOException{
		toServer.write(command.getBytes());
		lastCommand = new String(command);
		toServer.flush();
		
	}
	
	
	/**
	 * send command to the server
	 * @param command the command to execute on the server
	 * @throws IOException
	 */
	public void send(String command) throws IOException {
		command += "; echo \"" + terminator + "\"\n";
		toServer.write(command.getBytes());
		lastCommand = new String(command);
		toServer.flush();
	}
	
	/**
	 * disconnect from the current channel/server
	 */
	void disconnect(){
		if(channel.isConnected()){
			channel.disconnect();
		}
		
	}
	
	/**
	 * get the response form the server. the result of a command.  Looks for 'terminator' to determine if we have reached EOF
	 * @return a string with the message given from the server
	 * @throws IOException
	 * @throws InterruptedException
	 */
	String getServerResponse() throws IOException, InterruptedException {
		
		System.out.println("checkpoint 1 getserverresponse");
		String result = new String();
		StringBuilder builder = new StringBuilder();
		int count = 0;
		String line = "";

		while((line = fromServer.readLine()) != null){
			count++;
			//If line contains "terminator" it means the server has finished its response and we can stop listening(printing from it)
			if(line.contains(terminator) && !line.contains('"' + terminator + '"')&& count > 1) break;
			System.out.println(line);
			
		}
		
		System.out.println("Yeah. dat shit right here works");
		System.out.println("");
		
		int beginIndex = result.indexOf(terminator+"\"") + ((terminator+"\"").length());
		//result = result.substring(beginIndex);
		return result.replaceAll(escape(terminator), "").trim();
		
	}
	
	/**
	 * honestly have no idea what this is doing...
	 * @param terminator2
	 * @return
	 */
	private String escape(String string) {
		// TODO Auto-generated method stub
		return language.matcher(string).replaceAll("\\\\$1");
	}

	/**
	 * contains all necesarry operations regarding the user connecting to the Server
	 * @author student
	 *
	 */
	private static class MyUserInfo implements UserInfo{
		
		private String password;

		public void setPassword(String password){
			this.password = password;
			
		}
		
		@Override
		public String getPassphrase() {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public String getPassword() {
			// TODO Auto-generated method stub
			return password;
		}

		@Override
		public boolean promptPassphrase(String arg0) {
			// TODO Auto-generated method stub
			return false;
		}

		@Override
		public boolean promptPassword(String arg0) {
			// TODO Auto-generated method stub
			return true;
		}

		@Override
		public boolean promptYesNo(String arg0) {
			// TODO Auto-generated method stub
			return true;
		}

		@Override
		public void showMessage(String arg0) {
			// TODO Auto-generated method stub
			System.out.println(arg0);
			
		}
		
	}

}
